home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet bezpieczenstwa / mini Pentoo LiveCD 2006.1 / mpentoo-2006.1.iso / livecd.squashfs / usr / lib / python2.4 / idlelib / configDialog.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2005-10-18  |  43KB  |  1,102 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.4)
  3.  
  4. '''IDLE Configuration Dialog: support user customization of IDLE by GUI
  5.  
  6. Customize font faces, sizes, and colorization attributes.  Set indentation
  7. defaults.  Customize keybindings.  Colorization and keybindings can be
  8. saved as user defined sets.  Select startup options including shell/editor
  9. and default window size.  Define additional help sources.
  10.  
  11. Note that tab width in IDLE is currently fixed at eight due to Tk issues.
  12. Refer to comment in EditorWindow autoindent code for details.
  13.  
  14. '''
  15. from Tkinter import *
  16. import tkMessageBox
  17. import tkColorChooser
  18. import tkFont
  19. import string
  20. import copy
  21. from configHandler import idleConf
  22. from dynOptionMenuWidget import DynOptionMenu
  23. from tabpage import TabPageSet
  24. from keybindingDialog import GetKeysDialog
  25. from configSectionNameDialog import GetCfgSectionNameDialog
  26. from configHelpSourceEdit import GetHelpSourceDialog
  27.  
  28. class ConfigDialog(Toplevel):
  29.     '''
  30.     configuration dialog for idle
  31.     '''
  32.     
  33.     def __init__(self, parent, title):
  34.         Toplevel.__init__(self, parent)
  35.         self.configure(borderwidth = 5)
  36.         self.geometry('+%d+%d' % (parent.winfo_rootx() + 20, parent.winfo_rooty() + 30))
  37.         self.themeElements = {
  38.             'Normal Text': ('normal', '00'),
  39.             'Python Keywords': ('keyword', '01'),
  40.             'Python Definitions': ('definition', '02'),
  41.             'Python Builtins': ('builtin', '03'),
  42.             'Python Comments': ('comment', '04'),
  43.             'Python Strings': ('string', '05'),
  44.             'Selected Text': ('hilite', '06'),
  45.             'Found Text': ('hit', '07'),
  46.             'Cursor': ('cursor', '08'),
  47.             'Error Text': ('error', '09'),
  48.             'Shell Normal Text': ('console', '10'),
  49.             'Shell Stdout Text': ('stdout', '11'),
  50.             'Shell Stderr Text': ('stderr', '12') }
  51.         self.ResetChangedItems()
  52.         self.CreateWidgets()
  53.         self.resizable(height = FALSE, width = FALSE)
  54.         self.transient(parent)
  55.         self.grab_set()
  56.         self.protocol('WM_DELETE_WINDOW', self.Cancel)
  57.         self.parent = parent
  58.         self.tabPages.focus_set()
  59.         self.LoadConfigs()
  60.         self.AttachVarCallbacks()
  61.         self.wait_window()
  62.  
  63.     
  64.     def CreateWidgets(self):
  65.         self.tabPages = TabPageSet(self, pageNames = [
  66.             'Fonts/Tabs',
  67.             'Highlighting',
  68.             'Keys',
  69.             'General'])
  70.         self.tabPages.ChangePage()
  71.         frameActionButtons = Frame(self)
  72.         self.buttonHelp = Button(frameActionButtons, text = 'Help', command = self.Help, takefocus = FALSE)
  73.         self.buttonOk = Button(frameActionButtons, text = 'Ok', command = self.Ok, takefocus = FALSE)
  74.         self.buttonApply = Button(frameActionButtons, text = 'Apply', command = self.Apply, takefocus = FALSE)
  75.         self.buttonCancel = Button(frameActionButtons, text = 'Cancel', command = self.Cancel, takefocus = FALSE)
  76.         self.CreatePageFontTab()
  77.         self.CreatePageHighlight()
  78.         self.CreatePageKeys()
  79.         self.CreatePageGeneral()
  80.         self.buttonHelp.pack(side = RIGHT, padx = 5, pady = 5)
  81.         self.buttonOk.pack(side = LEFT, padx = 5, pady = 5)
  82.         self.buttonApply.pack(side = LEFT, padx = 5, pady = 5)
  83.         self.buttonCancel.pack(side = LEFT, padx = 5, pady = 5)
  84.         frameActionButtons.pack(side = BOTTOM)
  85.         self.tabPages.pack(side = TOP, expand = TRUE, fill = BOTH)
  86.  
  87.     
  88.     def CreatePageFontTab(self):
  89.         self.fontSize = StringVar(self)
  90.         self.fontBold = BooleanVar(self)
  91.         self.fontName = StringVar(self)
  92.         self.spaceNum = IntVar(self)
  93.         self.indentBySpaces = BooleanVar(self)
  94.         self.editFont = tkFont.Font(self, ('courier', 10, 'normal'))
  95.         frame = self.tabPages.pages['Fonts/Tabs']['page']
  96.         frameFont = Frame(frame, borderwidth = 2, relief = GROOVE)
  97.         frameIndent = Frame(frame, borderwidth = 2, relief = GROOVE)
  98.         labelFontTitle = Label(frameFont, text = 'Set Base Editor Font')
  99.         frameFontName = Frame(frameFont)
  100.         frameFontParam = Frame(frameFont)
  101.         labelFontNameTitle = Label(frameFontName, justify = LEFT, text = 'Font :')
  102.         self.listFontName = Listbox(frameFontName, height = 5, takefocus = FALSE, exportselection = FALSE)
  103.         self.listFontName.bind('<ButtonRelease-1>', self.OnListFontButtonRelease)
  104.         scrollFont = Scrollbar(frameFontName)
  105.         scrollFont.config(command = self.listFontName.yview)
  106.         self.listFontName.config(yscrollcommand = scrollFont.set)
  107.         labelFontSizeTitle = Label(frameFontParam, text = 'Size :')
  108.         self.optMenuFontSize = DynOptionMenu(frameFontParam, self.fontSize, None, command = self.SetFontSample)
  109.         checkFontBold = Checkbutton(frameFontParam, variable = self.fontBold, onvalue = 1, offvalue = 0, text = 'Bold', command = self.SetFontSample)
  110.         frameFontSample = Frame(frameFont, relief = SOLID, borderwidth = 1)
  111.         self.labelFontSample = Label(frameFontSample, text = 'AaBbCcDdEe\nFfGgHhIiJjK\n1234567890\n#:+=(){}[]', justify = LEFT, font = self.editFont)
  112.         labelIndentTitle = Label(frameIndent, text = 'Set Indentation Defaults')
  113.         frameIndentType = Frame(frameIndent)
  114.         frameIndentSize = Frame(frameIndent)
  115.         labelIndentTypeTitle = Label(frameIndentType, text = 'Choose indentation type :')
  116.         radioUseSpaces = Radiobutton(frameIndentType, variable = self.indentBySpaces, value = 1, text = 'Tab key inserts spaces')
  117.         radioUseTabs = Radiobutton(frameIndentType, variable = self.indentBySpaces, value = 0, text = 'Tab key inserts tabs')
  118.         labelIndentSizeTitle = Label(frameIndentSize, text = 'Choose indentation size :')
  119.         labelSpaceNumTitle = Label(frameIndentSize, justify = LEFT, text = 'indent width')
  120.         self.scaleSpaceNum = Scale(frameIndentSize, variable = self.spaceNum, orient = 'horizontal', tickinterval = 2, from_ = 2, to = 16)
  121.         frameFont.pack(side = LEFT, padx = 5, pady = 10, expand = TRUE, fill = BOTH)
  122.         frameIndent.pack(side = LEFT, padx = 5, pady = 10, fill = Y)
  123.         labelFontTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  124.         frameFontName.pack(side = TOP, padx = 5, pady = 5, fill = X)
  125.         frameFontParam.pack(side = TOP, padx = 5, pady = 5, fill = X)
  126.         labelFontNameTitle.pack(side = TOP, anchor = W)
  127.         self.listFontName.pack(side = LEFT, expand = TRUE, fill = X)
  128.         scrollFont.pack(side = LEFT, fill = Y)
  129.         labelFontSizeTitle.pack(side = LEFT, anchor = W)
  130.         self.optMenuFontSize.pack(side = LEFT, anchor = W)
  131.         checkFontBold.pack(side = LEFT, anchor = W, padx = 20)
  132.         frameFontSample.pack(side = TOP, padx = 5, pady = 5, expand = TRUE, fill = BOTH)
  133.         self.labelFontSample.pack(expand = TRUE, fill = BOTH)
  134.         labelIndentTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  135.         frameIndentType.pack(side = TOP, padx = 5, fill = X)
  136.         frameIndentSize.pack(side = TOP, padx = 5, pady = 5, fill = BOTH)
  137.         labelIndentTypeTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  138.         radioUseSpaces.pack(side = TOP, anchor = W, padx = 5)
  139.         radioUseTabs.pack(side = TOP, anchor = W, padx = 5)
  140.         labelIndentSizeTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  141.         labelSpaceNumTitle.pack(side = TOP, anchor = W, padx = 5)
  142.         self.scaleSpaceNum.pack(side = TOP, padx = 5, fill = X)
  143.         return frame
  144.  
  145.     
  146.     def CreatePageHighlight(self):
  147.         self.builtinTheme = StringVar(self)
  148.         self.customTheme = StringVar(self)
  149.         self.fgHilite = BooleanVar(self)
  150.         self.colour = StringVar(self)
  151.         self.fontName = StringVar(self)
  152.         self.themeIsBuiltin = BooleanVar(self)
  153.         self.highlightTarget = StringVar(self)
  154.         frame = self.tabPages.pages['Highlighting']['page']
  155.         frameCustom = Frame(frame, borderwidth = 2, relief = GROOVE)
  156.         frameTheme = Frame(frame, borderwidth = 2, relief = GROOVE)
  157.         self.textHighlightSample = Text(frameCustom, relief = SOLID, borderwidth = 1, font = ('courier', 12, ''), cursor = 'hand2', width = 21, height = 10, takefocus = FALSE, highlightthickness = 0, wrap = NONE)
  158.         text = self.textHighlightSample
  159.         text.bind('<Double-Button-1>', (lambda e: 'break'))
  160.         text.bind('<B1-Motion>', (lambda e: 'break'))
  161.         textAndTags = (('#you can click here', 'comment'), ('\n', 'normal'), ('#to choose items', 'comment'), ('\n', 'normal'), ('def', 'keyword'), (' ', 'normal'), ('func', 'definition'), ('(param):', 'normal'), ('\n  ', 'normal'), ('"""string"""', 'string'), ('\n  var0 = ', 'normal'), ("'string'", 'string'), ('\n  var1 = ', 'normal'), ("'selected'", 'hilite'), ('\n  var2 = ', 'normal'), ("'found'", 'hit'), ('\n  var3 = ', 'normal'), ('list', 'builtin'), ('(', 'normal'), ('None', 'builtin'), (')\n\n', 'normal'), (' error ', 'error'), (' ', 'normal'), ('cursor |', 'cursor'), ('\n ', 'normal'), ('shell', 'console'), (' ', 'normal'), ('stdout', 'stdout'), (' ', 'normal'), ('stderr', 'stderr'), ('\n', 'normal'))
  162.         for txTa in textAndTags:
  163.             text.insert(END, txTa[0], txTa[1])
  164.         
  165.         for element in self.themeElements.keys():
  166.             text.tag_bind(self.themeElements[element][0], '<ButtonPress-1>', (lambda event, elem = element: event.widget.winfo_toplevel().highlightTarget.set(elem)))
  167.         
  168.         text.config(state = DISABLED)
  169.         self.frameColourSet = Frame(frameCustom, relief = SOLID, borderwidth = 1)
  170.         frameFgBg = Frame(frameCustom)
  171.         labelCustomTitle = Label(frameCustom, text = 'Set Custom Highlighting')
  172.         buttonSetColour = Button(self.frameColourSet, text = 'Choose Colour for :', command = self.GetColour, highlightthickness = 0)
  173.         self.optMenuHighlightTarget = DynOptionMenu(self.frameColourSet, self.highlightTarget, None, highlightthickness = 0)
  174.         self.radioFg = Radiobutton(frameFgBg, variable = self.fgHilite, value = 1, text = 'Foreground', command = self.SetColourSampleBinding)
  175.         self.radioBg = Radiobutton(frameFgBg, variable = self.fgHilite, value = 0, text = 'Background', command = self.SetColourSampleBinding)
  176.         self.fgHilite.set(1)
  177.         buttonSaveCustomTheme = Button(frameCustom, text = 'Save as New Custom Theme', command = self.SaveAsNewTheme)
  178.         labelThemeTitle = Label(frameTheme, text = 'Select a Highlighting Theme')
  179.         labelTypeTitle = Label(frameTheme, text = 'Select : ')
  180.         self.radioThemeBuiltin = Radiobutton(frameTheme, variable = self.themeIsBuiltin, value = 1, command = self.SetThemeType, text = 'a Built-in Theme')
  181.         self.radioThemeCustom = Radiobutton(frameTheme, variable = self.themeIsBuiltin, value = 0, command = self.SetThemeType, text = 'a Custom Theme')
  182.         self.optMenuThemeBuiltin = DynOptionMenu(frameTheme, self.builtinTheme, None, command = None)
  183.         self.optMenuThemeCustom = DynOptionMenu(frameTheme, self.customTheme, None, command = None)
  184.         self.buttonDeleteCustomTheme = Button(frameTheme, text = 'Delete Custom Theme', command = self.DeleteCustomTheme)
  185.         frameCustom.pack(side = LEFT, padx = 5, pady = 10, expand = TRUE, fill = BOTH)
  186.         frameTheme.pack(side = LEFT, padx = 5, pady = 10, fill = Y)
  187.         labelCustomTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  188.         self.frameColourSet.pack(side = TOP, padx = 5, pady = 5, expand = TRUE, fill = X)
  189.         frameFgBg.pack(side = TOP, padx = 5, pady = 0)
  190.         self.textHighlightSample.pack(side = TOP, padx = 5, pady = 5, expand = TRUE, fill = BOTH)
  191.         buttonSetColour.pack(side = TOP, expand = TRUE, fill = X, padx = 8, pady = 4)
  192.         self.optMenuHighlightTarget.pack(side = TOP, expand = TRUE, fill = X, padx = 8, pady = 3)
  193.         self.radioFg.pack(side = LEFT, anchor = E)
  194.         self.radioBg.pack(side = RIGHT, anchor = W)
  195.         buttonSaveCustomTheme.pack(side = BOTTOM, fill = X, padx = 5, pady = 5)
  196.         labelThemeTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  197.         labelTypeTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  198.         self.radioThemeBuiltin.pack(side = TOP, anchor = W, padx = 5)
  199.         self.radioThemeCustom.pack(side = TOP, anchor = W, padx = 5, pady = 2)
  200.         self.optMenuThemeBuiltin.pack(side = TOP, fill = X, padx = 5, pady = 5)
  201.         self.optMenuThemeCustom.pack(side = TOP, fill = X, anchor = W, padx = 5, pady = 5)
  202.         self.buttonDeleteCustomTheme.pack(side = TOP, fill = X, padx = 5, pady = 5)
  203.         return frame
  204.  
  205.     
  206.     def CreatePageKeys(self):
  207.         self.bindingTarget = StringVar(self)
  208.         self.builtinKeys = StringVar(self)
  209.         self.customKeys = StringVar(self)
  210.         self.keysAreBuiltin = BooleanVar(self)
  211.         self.keyBinding = StringVar(self)
  212.         frame = self.tabPages.pages['Keys']['page']
  213.         frameCustom = Frame(frame, borderwidth = 2, relief = GROOVE)
  214.         frameKeySets = Frame(frame, borderwidth = 2, relief = GROOVE)
  215.         frameTarget = Frame(frameCustom)
  216.         labelCustomTitle = Label(frameCustom, text = 'Set Custom Key Bindings')
  217.         labelTargetTitle = Label(frameTarget, text = 'Action - Key(s)')
  218.         scrollTargetY = Scrollbar(frameTarget)
  219.         scrollTargetX = Scrollbar(frameTarget, orient = HORIZONTAL)
  220.         self.listBindings = Listbox(frameTarget, takefocus = FALSE, exportselection = FALSE)
  221.         self.listBindings.bind('<ButtonRelease-1>', self.KeyBindingSelected)
  222.         scrollTargetY.config(command = self.listBindings.yview)
  223.         scrollTargetX.config(command = self.listBindings.xview)
  224.         self.listBindings.config(yscrollcommand = scrollTargetY.set)
  225.         self.listBindings.config(xscrollcommand = scrollTargetX.set)
  226.         self.buttonNewKeys = Button(frameCustom, text = 'Get New Keys for Selection', command = self.GetNewKeys, state = DISABLED)
  227.         buttonSaveCustomKeys = Button(frameCustom, text = 'Save as New Custom Key Set', command = self.SaveAsNewKeySet)
  228.         labelKeysTitle = Label(frameKeySets, text = 'Select a Key Set')
  229.         labelTypeTitle = Label(frameKeySets, text = 'Select : ')
  230.         self.radioKeysBuiltin = Radiobutton(frameKeySets, variable = self.keysAreBuiltin, value = 1, command = self.SetKeysType, text = 'a Built-in Key Set')
  231.         self.radioKeysCustom = Radiobutton(frameKeySets, variable = self.keysAreBuiltin, value = 0, command = self.SetKeysType, text = 'a Custom Key Set')
  232.         self.optMenuKeysBuiltin = DynOptionMenu(frameKeySets, self.builtinKeys, None, command = None)
  233.         self.optMenuKeysCustom = DynOptionMenu(frameKeySets, self.customKeys, None, command = None)
  234.         self.buttonDeleteCustomKeys = Button(frameKeySets, text = 'Delete Custom Key Set', command = self.DeleteCustomKeys)
  235.         frameCustom.pack(side = LEFT, padx = 5, pady = 5, expand = TRUE, fill = BOTH)
  236.         frameKeySets.pack(side = LEFT, padx = 5, pady = 5, fill = Y)
  237.         labelCustomTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  238.         buttonSaveCustomKeys.pack(side = BOTTOM, fill = X, padx = 5, pady = 5)
  239.         self.buttonNewKeys.pack(side = BOTTOM, fill = X, padx = 5, pady = 5)
  240.         frameTarget.pack(side = LEFT, padx = 5, pady = 5, expand = TRUE, fill = BOTH)
  241.         frameTarget.columnconfigure(0, weight = 1)
  242.         frameTarget.rowconfigure(1, weight = 1)
  243.         labelTargetTitle.grid(row = 0, column = 0, columnspan = 2, sticky = W)
  244.         self.listBindings.grid(row = 1, column = 0, sticky = NSEW)
  245.         scrollTargetY.grid(row = 1, column = 1, sticky = NS)
  246.         scrollTargetX.grid(row = 2, column = 0, sticky = EW)
  247.         labelKeysTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  248.         labelTypeTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  249.         self.radioKeysBuiltin.pack(side = TOP, anchor = W, padx = 5)
  250.         self.radioKeysCustom.pack(side = TOP, anchor = W, padx = 5, pady = 2)
  251.         self.optMenuKeysBuiltin.pack(side = TOP, fill = X, padx = 5, pady = 5)
  252.         self.optMenuKeysCustom.pack(side = TOP, fill = X, anchor = W, padx = 5, pady = 5)
  253.         self.buttonDeleteCustomKeys.pack(side = TOP, fill = X, padx = 5, pady = 5)
  254.         return frame
  255.  
  256.     
  257.     def CreatePageGeneral(self):
  258.         self.winWidth = StringVar(self)
  259.         self.winHeight = StringVar(self)
  260.         self.paraWidth = StringVar(self)
  261.         self.startupEdit = IntVar(self)
  262.         self.autoSave = IntVar(self)
  263.         self.encoding = StringVar(self)
  264.         self.userHelpBrowser = BooleanVar(self)
  265.         self.helpBrowser = StringVar(self)
  266.         frame = self.tabPages.pages['General']['page']
  267.         frameRun = Frame(frame, borderwidth = 2, relief = GROOVE)
  268.         frameSave = Frame(frame, borderwidth = 2, relief = GROOVE)
  269.         frameWinSize = Frame(frame, borderwidth = 2, relief = GROOVE)
  270.         frameParaSize = Frame(frame, borderwidth = 2, relief = GROOVE)
  271.         frameEncoding = Frame(frame, borderwidth = 2, relief = GROOVE)
  272.         frameHelp = Frame(frame, borderwidth = 2, relief = GROOVE)
  273.         labelRunTitle = Label(frameRun, text = 'Startup Preferences')
  274.         labelRunChoiceTitle = Label(frameRun, text = 'At Startup')
  275.         radioStartupEdit = Radiobutton(frameRun, variable = self.startupEdit, value = 1, command = self.SetKeysType, text = 'Open Edit Window')
  276.         radioStartupShell = Radiobutton(frameRun, variable = self.startupEdit, value = 0, command = self.SetKeysType, text = 'Open Shell Window')
  277.         labelSaveTitle = Label(frameSave, text = 'Autosave Preference')
  278.         labelRunSaveTitle = Label(frameSave, text = 'At Start of Run (F5)  ')
  279.         radioSaveAsk = Radiobutton(frameSave, variable = self.autoSave, value = 0, command = self.SetKeysType, text = 'Prompt to Save')
  280.         radioSaveAuto = Radiobutton(frameSave, variable = self.autoSave, value = 1, command = self.SetKeysType, text = 'No Prompt')
  281.         labelWinSizeTitle = Label(frameWinSize, text = 'Initial Window Size' + '  (in characters)')
  282.         labelWinWidthTitle = Label(frameWinSize, text = 'Width')
  283.         entryWinWidth = Entry(frameWinSize, textvariable = self.winWidth, width = 3)
  284.         labelWinHeightTitle = Label(frameWinSize, text = 'Height')
  285.         entryWinHeight = Entry(frameWinSize, textvariable = self.winHeight, width = 3)
  286.         labelParaWidthTitle = Label(frameParaSize, text = 'Paragraph reformat' + ' width (in characters)')
  287.         entryParaWidth = Entry(frameParaSize, textvariable = self.paraWidth, width = 3)
  288.         labelEncodingTitle = Label(frameEncoding, text = 'Default Source Encoding')
  289.         radioEncLocale = Radiobutton(frameEncoding, variable = self.encoding, value = 'locale', text = 'Locale-defined')
  290.         radioEncUTF8 = Radiobutton(frameEncoding, variable = self.encoding, value = 'utf-8', text = 'UTF-8')
  291.         radioEncNone = Radiobutton(frameEncoding, variable = self.encoding, value = 'none', text = 'None')
  292.         frameHelpList = Frame(frameHelp)
  293.         frameHelpListButtons = Frame(frameHelpList)
  294.         labelHelpListTitle = Label(frameHelpList, text = 'Additional Help Sources:')
  295.         scrollHelpList = Scrollbar(frameHelpList)
  296.         self.listHelp = Listbox(frameHelpList, height = 5, takefocus = FALSE, exportselection = FALSE)
  297.         scrollHelpList.config(command = self.listHelp.yview)
  298.         self.listHelp.config(yscrollcommand = scrollHelpList.set)
  299.         self.listHelp.bind('<ButtonRelease-1>', self.HelpSourceSelected)
  300.         self.buttonHelpListEdit = Button(frameHelpListButtons, text = 'Edit', state = DISABLED, width = 8, command = self.HelpListItemEdit)
  301.         self.buttonHelpListAdd = Button(frameHelpListButtons, text = 'Add', width = 8, command = self.HelpListItemAdd)
  302.         self.buttonHelpListRemove = Button(frameHelpListButtons, text = 'Remove', state = DISABLED, width = 8, command = self.HelpListItemRemove)
  303.         frameRun.pack(side = TOP, padx = 5, pady = 5, fill = X)
  304.         frameSave.pack(side = TOP, padx = 5, pady = 5, fill = X)
  305.         frameWinSize.pack(side = TOP, padx = 5, pady = 5, fill = X)
  306.         frameParaSize.pack(side = TOP, padx = 5, pady = 5, fill = X)
  307.         frameEncoding.pack(side = TOP, padx = 5, pady = 5, fill = X)
  308.         frameHelp.pack(side = TOP, padx = 5, pady = 5, expand = TRUE, fill = BOTH)
  309.         labelRunTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  310.         labelRunChoiceTitle.pack(side = LEFT, anchor = W, padx = 5, pady = 5)
  311.         radioStartupShell.pack(side = RIGHT, anchor = W, padx = 5, pady = 5)
  312.         radioStartupEdit.pack(side = RIGHT, anchor = W, padx = 5, pady = 5)
  313.         labelSaveTitle.pack(side = TOP, anchor = W, padx = 5, pady = 5)
  314.         labelRunSaveTitle.pack(side = LEFT, anchor = W, padx = 5, pady = 5)
  315.         radioSaveAuto.pack(side = RIGHT, anchor = W, padx = 5, pady = 5)
  316.         radioSaveAsk.pack(side = RIGHT, anchor = W, padx = 5, pady = 5)
  317.         labelWinSizeTitle.pack(side = LEFT, anchor = W, padx = 5, pady = 5)
  318.         entryWinHeight.pack(side = RIGHT, anchor = E, padx = 10, pady = 5)
  319.         labelWinHeightTitle.pack(side = RIGHT, anchor = E, pady = 5)
  320.         entryWinWidth.pack(side = RIGHT, anchor = E, padx = 10, pady = 5)
  321.         labelWinWidthTitle.pack(side = RIGHT, anchor = E, pady = 5)
  322.         labelParaWidthTitle.pack(side = LEFT, anchor = W, padx = 5, pady = 5)
  323.         entryParaWidth.pack(side = RIGHT, anchor = E, padx = 10, pady = 5)
  324.         labelEncodingTitle.pack(side = LEFT, anchor = W, padx = 5, pady = 5)
  325.         radioEncNone.pack(side = RIGHT, anchor = E, pady = 5)
  326.         radioEncUTF8.pack(side = RIGHT, anchor = E, pady = 5)
  327.         radioEncLocale.pack(side = RIGHT, anchor = E, pady = 5)
  328.         frameHelpListButtons.pack(side = RIGHT, padx = 5, pady = 5, fill = Y)
  329.         frameHelpList.pack(side = TOP, padx = 5, pady = 5, expand = TRUE, fill = BOTH)
  330.         labelHelpListTitle.pack(side = TOP, anchor = W)
  331.         scrollHelpList.pack(side = RIGHT, anchor = W, fill = Y)
  332.         self.listHelp.pack(side = LEFT, anchor = E, expand = TRUE, fill = BOTH)
  333.         self.buttonHelpListEdit.pack(side = TOP, anchor = W, pady = 5)
  334.         self.buttonHelpListAdd.pack(side = TOP, anchor = W)
  335.         self.buttonHelpListRemove.pack(side = TOP, anchor = W, pady = 5)
  336.         return frame
  337.  
  338.     
  339.     def AttachVarCallbacks(self):
  340.         self.fontSize.trace_variable('w', self.VarChanged_fontSize)
  341.         self.fontName.trace_variable('w', self.VarChanged_fontName)
  342.         self.fontBold.trace_variable('w', self.VarChanged_fontBold)
  343.         self.spaceNum.trace_variable('w', self.VarChanged_spaceNum)
  344.         self.indentBySpaces.trace_variable('w', self.VarChanged_indentBySpaces)
  345.         self.colour.trace_variable('w', self.VarChanged_colour)
  346.         self.builtinTheme.trace_variable('w', self.VarChanged_builtinTheme)
  347.         self.customTheme.trace_variable('w', self.VarChanged_customTheme)
  348.         self.themeIsBuiltin.trace_variable('w', self.VarChanged_themeIsBuiltin)
  349.         self.highlightTarget.trace_variable('w', self.VarChanged_highlightTarget)
  350.         self.keyBinding.trace_variable('w', self.VarChanged_keyBinding)
  351.         self.builtinKeys.trace_variable('w', self.VarChanged_builtinKeys)
  352.         self.customKeys.trace_variable('w', self.VarChanged_customKeys)
  353.         self.keysAreBuiltin.trace_variable('w', self.VarChanged_keysAreBuiltin)
  354.         self.winWidth.trace_variable('w', self.VarChanged_winWidth)
  355.         self.winHeight.trace_variable('w', self.VarChanged_winHeight)
  356.         self.paraWidth.trace_variable('w', self.VarChanged_paraWidth)
  357.         self.startupEdit.trace_variable('w', self.VarChanged_startupEdit)
  358.         self.autoSave.trace_variable('w', self.VarChanged_autoSave)
  359.         self.encoding.trace_variable('w', self.VarChanged_encoding)
  360.  
  361.     
  362.     def VarChanged_fontSize(self, *params):
  363.         value = self.fontSize.get()
  364.         self.AddChangedItem('main', 'EditorWindow', 'font-size', value)
  365.  
  366.     
  367.     def VarChanged_fontName(self, *params):
  368.         value = self.fontName.get()
  369.         self.AddChangedItem('main', 'EditorWindow', 'font', value)
  370.  
  371.     
  372.     def VarChanged_fontBold(self, *params):
  373.         value = self.fontBold.get()
  374.         self.AddChangedItem('main', 'EditorWindow', 'font-bold', value)
  375.  
  376.     
  377.     def VarChanged_indentBySpaces(self, *params):
  378.         value = self.indentBySpaces.get()
  379.         self.AddChangedItem('main', 'Indent', 'use-spaces', value)
  380.  
  381.     
  382.     def VarChanged_spaceNum(self, *params):
  383.         value = self.spaceNum.get()
  384.         self.AddChangedItem('main', 'Indent', 'num-spaces', value)
  385.  
  386.     
  387.     def VarChanged_colour(self, *params):
  388.         self.OnNewColourSet()
  389.  
  390.     
  391.     def VarChanged_builtinTheme(self, *params):
  392.         value = self.builtinTheme.get()
  393.         self.AddChangedItem('main', 'Theme', 'name', value)
  394.         self.PaintThemeSample()
  395.  
  396.     
  397.     def VarChanged_customTheme(self, *params):
  398.         value = self.customTheme.get()
  399.         if value != '- no custom themes -':
  400.             self.AddChangedItem('main', 'Theme', 'name', value)
  401.             self.PaintThemeSample()
  402.         
  403.  
  404.     
  405.     def VarChanged_themeIsBuiltin(self, *params):
  406.         value = self.themeIsBuiltin.get()
  407.         self.AddChangedItem('main', 'Theme', 'default', value)
  408.         if value:
  409.             self.VarChanged_builtinTheme()
  410.         else:
  411.             self.VarChanged_customTheme()
  412.  
  413.     
  414.     def VarChanged_highlightTarget(self, *params):
  415.         self.SetHighlightTarget()
  416.  
  417.     
  418.     def VarChanged_keyBinding(self, *params):
  419.         value = self.keyBinding.get()
  420.         keySet = self.customKeys.get()
  421.         event = self.listBindings.get(ANCHOR).split()[0]
  422.         if idleConf.IsCoreBinding(event):
  423.             self.AddChangedItem('keys', keySet, event, value)
  424.         else:
  425.             extName = idleConf.GetExtnNameForEvent(event)
  426.             extKeybindSection = extName + '_cfgBindings'
  427.             self.AddChangedItem('extensions', extKeybindSection, event, value)
  428.  
  429.     
  430.     def VarChanged_builtinKeys(self, *params):
  431.         value = self.builtinKeys.get()
  432.         self.AddChangedItem('main', 'Keys', 'name', value)
  433.         self.LoadKeysList(value)
  434.  
  435.     
  436.     def VarChanged_customKeys(self, *params):
  437.         value = self.customKeys.get()
  438.         if value != '- no custom keys -':
  439.             self.AddChangedItem('main', 'Keys', 'name', value)
  440.             self.LoadKeysList(value)
  441.         
  442.  
  443.     
  444.     def VarChanged_keysAreBuiltin(self, *params):
  445.         value = self.keysAreBuiltin.get()
  446.         self.AddChangedItem('main', 'Keys', 'default', value)
  447.         if value:
  448.             self.VarChanged_builtinKeys()
  449.         else:
  450.             self.VarChanged_customKeys()
  451.  
  452.     
  453.     def VarChanged_winWidth(self, *params):
  454.         value = self.winWidth.get()
  455.         self.AddChangedItem('main', 'EditorWindow', 'width', value)
  456.  
  457.     
  458.     def VarChanged_winHeight(self, *params):
  459.         value = self.winHeight.get()
  460.         self.AddChangedItem('main', 'EditorWindow', 'height', value)
  461.  
  462.     
  463.     def VarChanged_paraWidth(self, *params):
  464.         value = self.paraWidth.get()
  465.         self.AddChangedItem('main', 'FormatParagraph', 'paragraph', value)
  466.  
  467.     
  468.     def VarChanged_startupEdit(self, *params):
  469.         value = self.startupEdit.get()
  470.         self.AddChangedItem('main', 'General', 'editor-on-startup', value)
  471.  
  472.     
  473.     def VarChanged_autoSave(self, *params):
  474.         value = self.autoSave.get()
  475.         self.AddChangedItem('main', 'General', 'autosave', value)
  476.  
  477.     
  478.     def VarChanged_encoding(self, *params):
  479.         value = self.encoding.get()
  480.         self.AddChangedItem('main', 'EditorWindow', 'encoding', value)
  481.  
  482.     
  483.     def ResetChangedItems(self):
  484.         self.changedItems = {
  485.             'main': { },
  486.             'highlight': { },
  487.             'keys': { },
  488.             'extensions': { } }
  489.  
  490.     
  491.     def AddChangedItem(self, type, section, item, value):
  492.         value = str(value)
  493.         if not self.changedItems[type].has_key(section):
  494.             self.changedItems[type][section] = { }
  495.         
  496.         self.changedItems[type][section][item] = value
  497.  
  498.     
  499.     def GetDefaultItems(self):
  500.         dItems = {
  501.             'main': { },
  502.             'highlight': { },
  503.             'keys': { },
  504.             'extensions': { } }
  505.         for configType in dItems.keys():
  506.             sections = idleConf.GetSectionList('default', configType)
  507.             for section in sections:
  508.                 dItems[configType][section] = { }
  509.                 options = idleConf.defaultCfg[configType].GetOptionList(section)
  510.                 for option in options:
  511.                     dItems[configType][section][option] = idleConf.defaultCfg[configType].Get(section, option)
  512.                 
  513.             
  514.         
  515.         return dItems
  516.  
  517.     
  518.     def SetThemeType(self):
  519.         if self.themeIsBuiltin.get():
  520.             self.optMenuThemeBuiltin.config(state = NORMAL)
  521.             self.optMenuThemeCustom.config(state = DISABLED)
  522.             self.buttonDeleteCustomTheme.config(state = DISABLED)
  523.         else:
  524.             self.optMenuThemeBuiltin.config(state = DISABLED)
  525.             self.radioThemeCustom.config(state = NORMAL)
  526.             self.optMenuThemeCustom.config(state = NORMAL)
  527.             self.buttonDeleteCustomTheme.config(state = NORMAL)
  528.  
  529.     
  530.     def SetKeysType(self):
  531.         if self.keysAreBuiltin.get():
  532.             self.optMenuKeysBuiltin.config(state = NORMAL)
  533.             self.optMenuKeysCustom.config(state = DISABLED)
  534.             self.buttonDeleteCustomKeys.config(state = DISABLED)
  535.         else:
  536.             self.optMenuKeysBuiltin.config(state = DISABLED)
  537.             self.radioKeysCustom.config(state = NORMAL)
  538.             self.optMenuKeysCustom.config(state = NORMAL)
  539.             self.buttonDeleteCustomKeys.config(state = NORMAL)
  540.  
  541.     
  542.     def GetNewKeys(self):
  543.         listIndex = self.listBindings.index(ANCHOR)
  544.         binding = self.listBindings.get(listIndex)
  545.         bindName = binding.split()[0]
  546.         if self.keysAreBuiltin.get():
  547.             currentKeySetName = self.builtinKeys.get()
  548.         else:
  549.             currentKeySetName = self.customKeys.get()
  550.         currentBindings = idleConf.GetCurrentKeySet()
  551.         if currentKeySetName in self.changedItems['keys'].keys():
  552.             keySetChanges = self.changedItems['keys'][currentKeySetName]
  553.             for event in keySetChanges.keys():
  554.                 currentBindings[event] = keySetChanges[event].split()
  555.             
  556.         
  557.         currentKeySequences = currentBindings.values()
  558.         newKeys = GetKeysDialog(self, 'Get New Keys', bindName, currentKeySequences).result
  559.         if newKeys:
  560.             if self.keysAreBuiltin.get():
  561.                 message = 'Your changes will be saved as a new Custom Key Set. ' + 'Enter a name for your new Custom Key Set below.'
  562.                 newKeySet = self.GetNewKeysName(message)
  563.                 if not newKeySet:
  564.                     self.listBindings.select_set(listIndex)
  565.                     self.listBindings.select_anchor(listIndex)
  566.                     return None
  567.                 else:
  568.                     self.CreateNewKeySet(newKeySet)
  569.             
  570.             self.listBindings.delete(listIndex)
  571.             self.listBindings.insert(listIndex, bindName + ' - ' + newKeys)
  572.             self.listBindings.select_set(listIndex)
  573.             self.listBindings.select_anchor(listIndex)
  574.             self.keyBinding.set(newKeys)
  575.         else:
  576.             self.listBindings.select_set(listIndex)
  577.             self.listBindings.select_anchor(listIndex)
  578.  
  579.     
  580.     def GetNewKeysName(self, message):
  581.         usedNames = idleConf.GetSectionList('user', 'keys') + idleConf.GetSectionList('default', 'keys')
  582.         newKeySet = GetCfgSectionNameDialog(self, 'New Custom Key Set', message, usedNames).result
  583.         return newKeySet
  584.  
  585.     
  586.     def SaveAsNewKeySet(self):
  587.         newKeysName = self.GetNewKeysName('New Key Set Name:')
  588.         if newKeysName:
  589.             self.CreateNewKeySet(newKeysName)
  590.         
  591.  
  592.     
  593.     def KeyBindingSelected(self, event):
  594.         self.buttonNewKeys.config(state = NORMAL)
  595.  
  596.     
  597.     def CreateNewKeySet(self, newKeySetName):
  598.         if self.keysAreBuiltin.get():
  599.             prevKeySetName = self.builtinKeys.get()
  600.         else:
  601.             prevKeySetName = self.customKeys.get()
  602.         prevKeys = idleConf.GetCoreKeys(prevKeySetName)
  603.         newKeys = { }
  604.         for event in prevKeys.keys():
  605.             eventName = event[2:-2]
  606.             binding = string.join(prevKeys[event])
  607.             newKeys[eventName] = binding
  608.         
  609.         if prevKeySetName in self.changedItems['keys'].keys():
  610.             keySetChanges = self.changedItems['keys'][prevKeySetName]
  611.             for event in keySetChanges.keys():
  612.                 newKeys[event] = keySetChanges[event]
  613.             
  614.         
  615.         self.SaveNewKeySet(newKeySetName, newKeys)
  616.         customKeyList = idleConf.GetSectionList('user', 'keys')
  617.         customKeyList.sort()
  618.         self.optMenuKeysCustom.SetMenu(customKeyList, newKeySetName)
  619.         self.keysAreBuiltin.set(0)
  620.         self.SetKeysType()
  621.  
  622.     
  623.     def LoadKeysList(self, keySetName):
  624.         reselect = 0
  625.         newKeySet = 0
  626.         if self.listBindings.curselection():
  627.             reselect = 1
  628.             listIndex = self.listBindings.index(ANCHOR)
  629.         
  630.         keySet = idleConf.GetKeySet(keySetName)
  631.         bindNames = keySet.keys()
  632.         bindNames.sort()
  633.         self.listBindings.delete(0, END)
  634.         for bindName in bindNames:
  635.             key = string.join(keySet[bindName])
  636.             bindName = bindName[2:-2]
  637.             if keySetName in self.changedItems['keys'].keys():
  638.                 if bindName in self.changedItems['keys'][keySetName].keys():
  639.                     key = self.changedItems['keys'][keySetName][bindName]
  640.                 
  641.             
  642.             self.listBindings.insert(END, bindName + ' - ' + key)
  643.         
  644.         if reselect:
  645.             self.listBindings.see(listIndex)
  646.             self.listBindings.select_set(listIndex)
  647.             self.listBindings.select_anchor(listIndex)
  648.         
  649.  
  650.     
  651.     def DeleteCustomKeys(self):
  652.         keySetName = self.customKeys.get()
  653.         if not tkMessageBox.askyesno('Delete Key Set', 'Are you sure you wish ' + 'to delete the key set %r ?' % keySetName, parent = self):
  654.             return None
  655.         
  656.         idleConf.userCfg['keys'].remove_section(keySetName)
  657.         if self.changedItems['keys'].has_key(keySetName):
  658.             del self.changedItems['keys'][keySetName]
  659.         
  660.         idleConf.userCfg['keys'].Save()
  661.         itemList = idleConf.GetSectionList('user', 'keys')
  662.         itemList.sort()
  663.         if not itemList:
  664.             self.radioKeysCustom.config(state = DISABLED)
  665.             self.optMenuKeysCustom.SetMenu(itemList, '- no custom keys -')
  666.         else:
  667.             self.optMenuKeysCustom.SetMenu(itemList, itemList[0])
  668.         self.keysAreBuiltin.set(idleConf.defaultCfg['main'].Get('Keys', 'default'))
  669.         self.builtinKeys.set(idleConf.defaultCfg['main'].Get('Keys', 'name'))
  670.         self.Apply()
  671.         self.SetKeysType()
  672.  
  673.     
  674.     def DeleteCustomTheme(self):
  675.         themeName = self.customTheme.get()
  676.         if not tkMessageBox.askyesno('Delete Theme', 'Are you sure you wish ' + 'to delete the theme %r ?' % (themeName,), parent = self):
  677.             return None
  678.         
  679.         idleConf.userCfg['highlight'].remove_section(themeName)
  680.         if self.changedItems['highlight'].has_key(themeName):
  681.             del self.changedItems['highlight'][themeName]
  682.         
  683.         idleConf.userCfg['highlight'].Save()
  684.         itemList = idleConf.GetSectionList('user', 'highlight')
  685.         itemList.sort()
  686.         if not itemList:
  687.             self.radioThemeCustom.config(state = DISABLED)
  688.             self.optMenuThemeCustom.SetMenu(itemList, '- no custom themes -')
  689.         else:
  690.             self.optMenuThemeCustom.SetMenu(itemList, itemList[0])
  691.         self.themeIsBuiltin.set(idleConf.defaultCfg['main'].Get('Theme', 'default'))
  692.         self.builtinTheme.set(idleConf.defaultCfg['main'].Get('Theme', 'name'))
  693.         self.Apply()
  694.         self.SetThemeType()
  695.  
  696.     
  697.     def GetColour(self):
  698.         target = self.highlightTarget.get()
  699.         prevColour = self.frameColourSet.cget('bg')
  700.         (rgbTuplet, colourString) = tkColorChooser.askcolor(parent = self, title = 'Pick new colour for : ' + target, initialcolor = prevColour)
  701.         if colourString and colourString != prevColour:
  702.             if self.themeIsBuiltin.get():
  703.                 message = 'Your changes will be saved as a new Custom Theme. ' + 'Enter a name for your new Custom Theme below.'
  704.                 newTheme = self.GetNewThemeName(message)
  705.                 if not newTheme:
  706.                     return None
  707.                 else:
  708.                     self.CreateNewTheme(newTheme)
  709.                     self.colour.set(colourString)
  710.             else:
  711.                 self.colour.set(colourString)
  712.         
  713.  
  714.     
  715.     def OnNewColourSet(self):
  716.         newColour = self.colour.get()
  717.         self.frameColourSet.config(bg = newColour)
  718.         if self.fgHilite.get():
  719.             plane = 'foreground'
  720.         else:
  721.             plane = 'background'
  722.         sampleElement = self.themeElements[self.highlightTarget.get()][0]
  723.         self.textHighlightSample.tag_config(sampleElement, **{
  724.             plane: newColour })
  725.         theme = self.customTheme.get()
  726.         themeElement = sampleElement + '-' + plane
  727.         self.AddChangedItem('highlight', theme, themeElement, newColour)
  728.  
  729.     
  730.     def GetNewThemeName(self, message):
  731.         usedNames = idleConf.GetSectionList('user', 'highlight') + idleConf.GetSectionList('default', 'highlight')
  732.         newTheme = GetCfgSectionNameDialog(self, 'New Custom Theme', message, usedNames).result
  733.         return newTheme
  734.  
  735.     
  736.     def SaveAsNewTheme(self):
  737.         newThemeName = self.GetNewThemeName('New Theme Name:')
  738.         if newThemeName:
  739.             self.CreateNewTheme(newThemeName)
  740.         
  741.  
  742.     
  743.     def CreateNewTheme(self, newThemeName):
  744.         if self.themeIsBuiltin.get():
  745.             themeType = 'default'
  746.             themeName = self.builtinTheme.get()
  747.         else:
  748.             themeType = 'user'
  749.             themeName = self.customTheme.get()
  750.         newTheme = idleConf.GetThemeDict(themeType, themeName)
  751.         if themeName in self.changedItems['highlight'].keys():
  752.             themeChanges = self.changedItems['highlight'][themeName]
  753.             for element in themeChanges.keys():
  754.                 newTheme[element] = themeChanges[element]
  755.             
  756.         
  757.         self.SaveNewTheme(newThemeName, newTheme)
  758.         customThemeList = idleConf.GetSectionList('user', 'highlight')
  759.         customThemeList.sort()
  760.         self.optMenuThemeCustom.SetMenu(customThemeList, newThemeName)
  761.         self.themeIsBuiltin.set(0)
  762.         self.SetThemeType()
  763.  
  764.     
  765.     def OnListFontButtonRelease(self, event):
  766.         font = self.listFontName.get(ANCHOR)
  767.         self.fontName.set(font.lower())
  768.         self.SetFontSample()
  769.  
  770.     
  771.     def SetFontSample(self, event = None):
  772.         fontName = self.fontName.get()
  773.         if self.fontBold.get():
  774.             fontWeight = tkFont.BOLD
  775.         else:
  776.             fontWeight = tkFont.NORMAL
  777.         self.editFont.config(size = self.fontSize.get(), weight = fontWeight, family = fontName)
  778.  
  779.     
  780.     def SetHighlightTarget(self):
  781.         if self.highlightTarget.get() == 'Cursor':
  782.             self.radioFg.config(state = DISABLED)
  783.             self.radioBg.config(state = DISABLED)
  784.             self.fgHilite.set(1)
  785.         else:
  786.             self.radioFg.config(state = NORMAL)
  787.             self.radioBg.config(state = NORMAL)
  788.             self.fgHilite.set(1)
  789.         self.SetColourSample()
  790.  
  791.     
  792.     def SetColourSampleBinding(self, *args):
  793.         self.SetColourSample()
  794.  
  795.     
  796.     def SetColourSample(self):
  797.         tag = self.themeElements[self.highlightTarget.get()][0]
  798.         if self.fgHilite.get():
  799.             plane = 'foreground'
  800.         else:
  801.             plane = 'background'
  802.         colour = self.textHighlightSample.tag_cget(tag, plane)
  803.         self.frameColourSet.config(bg = colour)
  804.  
  805.     
  806.     def PaintThemeSample(self):
  807.         if self.themeIsBuiltin.get():
  808.             theme = self.builtinTheme.get()
  809.         else:
  810.             theme = self.customTheme.get()
  811.         for elementTitle in self.themeElements.keys():
  812.             element = self.themeElements[elementTitle][0]
  813.             colours = idleConf.GetHighlight(theme, element)
  814.             if element == 'cursor':
  815.                 colours['background'] = idleConf.GetHighlight(theme, 'normal', fgBg = 'bg')
  816.             
  817.             if theme in self.changedItems['highlight'].keys():
  818.                 themeDict = self.changedItems['highlight'][theme]
  819.                 if themeDict.has_key(element + '-foreground'):
  820.                     colours['foreground'] = themeDict[element + '-foreground']
  821.                 
  822.                 if themeDict.has_key(element + '-background'):
  823.                     colours['background'] = themeDict[element + '-background']
  824.                 
  825.             
  826.             self.textHighlightSample.tag_config(element, **colours)
  827.         
  828.         self.SetColourSample()
  829.  
  830.     
  831.     def HelpSourceSelected(self, event):
  832.         self.SetHelpListButtonStates()
  833.  
  834.     
  835.     def SetHelpListButtonStates(self):
  836.         if self.listHelp.size() < 1:
  837.             self.buttonHelpListEdit.config(state = DISABLED)
  838.             self.buttonHelpListRemove.config(state = DISABLED)
  839.         elif self.listHelp.curselection():
  840.             self.buttonHelpListEdit.config(state = NORMAL)
  841.             self.buttonHelpListRemove.config(state = NORMAL)
  842.         else:
  843.             self.buttonHelpListEdit.config(state = DISABLED)
  844.             self.buttonHelpListRemove.config(state = DISABLED)
  845.  
  846.     
  847.     def HelpListItemAdd(self):
  848.         helpSource = GetHelpSourceDialog(self, 'New Help Source').result
  849.         if helpSource:
  850.             self.userHelpList.append((helpSource[0], helpSource[1]))
  851.             self.listHelp.insert(END, helpSource[0])
  852.             self.UpdateUserHelpChangedItems()
  853.         
  854.         self.SetHelpListButtonStates()
  855.  
  856.     
  857.     def HelpListItemEdit(self):
  858.         itemIndex = self.listHelp.index(ANCHOR)
  859.         helpSource = self.userHelpList[itemIndex]
  860.         newHelpSource = GetHelpSourceDialog(self, 'Edit Help Source', menuItem = helpSource[0], filePath = helpSource[1]).result
  861.         if not newHelpSource or newHelpSource == helpSource:
  862.             return None
  863.         
  864.         self.userHelpList[itemIndex] = newHelpSource
  865.         self.listHelp.delete(itemIndex)
  866.         self.listHelp.insert(itemIndex, newHelpSource[0])
  867.         self.UpdateUserHelpChangedItems()
  868.         self.SetHelpListButtonStates()
  869.  
  870.     
  871.     def HelpListItemRemove(self):
  872.         itemIndex = self.listHelp.index(ANCHOR)
  873.         del self.userHelpList[itemIndex]
  874.         self.listHelp.delete(itemIndex)
  875.         self.UpdateUserHelpChangedItems()
  876.         self.SetHelpListButtonStates()
  877.  
  878.     
  879.     def UpdateUserHelpChangedItems(self):
  880.         '''Clear and rebuild the HelpFiles section in self.changedItems'''
  881.         self.changedItems['main']['HelpFiles'] = { }
  882.         for num in range(1, len(self.userHelpList) + 1):
  883.             self.AddChangedItem('main', 'HelpFiles', str(num), string.join(self.userHelpList[num - 1][:2], ';'))
  884.         
  885.  
  886.     
  887.     def LoadFontCfg(self):
  888.         fonts = list(tkFont.families(self))
  889.         fonts.sort()
  890.         for font in fonts:
  891.             self.listFontName.insert(END, font)
  892.         
  893.         configuredFont = idleConf.GetOption('main', 'EditorWindow', 'font', default = 'courier')
  894.         lc_configuredFont = configuredFont.lower()
  895.         self.fontName.set(lc_configuredFont)
  896.         lc_fonts = [ s.lower() for s in fonts ]
  897.         fontSize = idleConf.GetOption('main', 'EditorWindow', 'font-size', default = '10')
  898.         self.optMenuFontSize.SetMenu(('7', '8', '9', '10', '11', '12', '13', '14', '16', '18', '20', '22'), fontSize)
  899.         self.fontBold.set(idleConf.GetOption('main', 'EditorWindow', 'font-bold', default = 0, type = 'bool'))
  900.         self.SetFontSample()
  901.  
  902.     
  903.     def LoadTabCfg(self):
  904.         spaceIndent = idleConf.GetOption('main', 'Indent', 'use-spaces', default = 1, type = 'bool')
  905.         self.indentBySpaces.set(spaceIndent)
  906.         spaceNum = idleConf.GetOption('main', 'Indent', 'num-spaces', default = 4, type = 'int')
  907.         self.spaceNum.set(spaceNum)
  908.  
  909.     
  910.     def LoadThemeCfg(self):
  911.         self.themeIsBuiltin.set(idleConf.GetOption('main', 'Theme', 'default', type = 'bool', default = 1))
  912.         currentOption = idleConf.CurrentTheme()
  913.         if self.themeIsBuiltin.get():
  914.             itemList = idleConf.GetSectionList('default', 'highlight')
  915.             itemList.sort()
  916.             self.optMenuThemeBuiltin.SetMenu(itemList, currentOption)
  917.             itemList = idleConf.GetSectionList('user', 'highlight')
  918.             itemList.sort()
  919.             if not itemList:
  920.                 self.radioThemeCustom.config(state = DISABLED)
  921.                 self.customTheme.set('- no custom themes -')
  922.             else:
  923.                 self.optMenuThemeCustom.SetMenu(itemList, itemList[0])
  924.         else:
  925.             itemList = idleConf.GetSectionList('user', 'highlight')
  926.             itemList.sort()
  927.             self.optMenuThemeCustom.SetMenu(itemList, currentOption)
  928.             itemList = idleConf.GetSectionList('default', 'highlight')
  929.             itemList.sort()
  930.             self.optMenuThemeBuiltin.SetMenu(itemList, itemList[0])
  931.         self.SetThemeType()
  932.         themeNames = self.themeElements.keys()
  933.         themeNames.sort(self._ConfigDialog__ThemeNameIndexCompare)
  934.         self.optMenuHighlightTarget.SetMenu(themeNames, themeNames[0])
  935.         self.PaintThemeSample()
  936.         self.SetHighlightTarget()
  937.  
  938.     
  939.     def __ThemeNameIndexCompare(self, a, b):
  940.         if self.themeElements[a][1] < self.themeElements[b][1]:
  941.             return -1
  942.         elif self.themeElements[a][1] == self.themeElements[b][1]:
  943.             return 0
  944.         else:
  945.             return 1
  946.  
  947.     
  948.     def LoadKeyCfg(self):
  949.         self.keysAreBuiltin.set(idleConf.GetOption('main', 'Keys', 'default', type = 'bool', default = 1))
  950.         currentOption = idleConf.CurrentKeys()
  951.         if self.keysAreBuiltin.get():
  952.             itemList = idleConf.GetSectionList('default', 'keys')
  953.             itemList.sort()
  954.             self.optMenuKeysBuiltin.SetMenu(itemList, currentOption)
  955.             itemList = idleConf.GetSectionList('user', 'keys')
  956.             itemList.sort()
  957.             if not itemList:
  958.                 self.radioKeysCustom.config(state = DISABLED)
  959.                 self.customKeys.set('- no custom keys -')
  960.             else:
  961.                 self.optMenuKeysCustom.SetMenu(itemList, itemList[0])
  962.         else:
  963.             itemList = idleConf.GetSectionList('user', 'keys')
  964.             itemList.sort()
  965.             self.optMenuKeysCustom.SetMenu(itemList, currentOption)
  966.             itemList = idleConf.GetSectionList('default', 'keys')
  967.             itemList.sort()
  968.             self.optMenuKeysBuiltin.SetMenu(itemList, itemList[0])
  969.         self.SetKeysType()
  970.         keySetName = idleConf.CurrentKeys()
  971.         self.LoadKeysList(keySetName)
  972.  
  973.     
  974.     def LoadGeneralCfg(self):
  975.         self.startupEdit.set(idleConf.GetOption('main', 'General', 'editor-on-startup', default = 1, type = 'bool'))
  976.         self.autoSave.set(idleConf.GetOption('main', 'General', 'autosave', default = 0, type = 'bool'))
  977.         self.winWidth.set(idleConf.GetOption('main', 'EditorWindow', 'width'))
  978.         self.winHeight.set(idleConf.GetOption('main', 'EditorWindow', 'height'))
  979.         self.paraWidth.set(idleConf.GetOption('main', 'FormatParagraph', 'paragraph'))
  980.         self.encoding.set(idleConf.GetOption('main', 'EditorWindow', 'encoding', default = 'none'))
  981.         self.userHelpList = idleConf.GetAllExtraHelpSourcesList()
  982.         for helpItem in self.userHelpList:
  983.             self.listHelp.insert(END, helpItem[0])
  984.         
  985.         self.SetHelpListButtonStates()
  986.  
  987.     
  988.     def LoadConfigs(self):
  989.         '''
  990.         load configuration from default and user config files and populate
  991.         the widgets on the config dialog pages.
  992.         '''
  993.         self.LoadFontCfg()
  994.         self.LoadTabCfg()
  995.         self.LoadThemeCfg()
  996.         self.LoadKeyCfg()
  997.         self.LoadGeneralCfg()
  998.  
  999.     
  1000.     def SaveNewKeySet(self, keySetName, keySet):
  1001.         '''
  1002.         save a newly created core key set.
  1003.         keySetName - string, the name of the new key set
  1004.         keySet - dictionary containing the new key set
  1005.         '''
  1006.         if not idleConf.userCfg['keys'].has_section(keySetName):
  1007.             idleConf.userCfg['keys'].add_section(keySetName)
  1008.         
  1009.         for event in keySet.keys():
  1010.             value = keySet[event]
  1011.             idleConf.userCfg['keys'].SetOption(keySetName, event, value)
  1012.         
  1013.  
  1014.     
  1015.     def SaveNewTheme(self, themeName, theme):
  1016.         '''
  1017.         save a newly created theme.
  1018.         themeName - string, the name of the new theme
  1019.         theme - dictionary containing the new theme
  1020.         '''
  1021.         if not idleConf.userCfg['highlight'].has_section(themeName):
  1022.             idleConf.userCfg['highlight'].add_section(themeName)
  1023.         
  1024.         for element in theme.keys():
  1025.             value = theme[element]
  1026.             idleConf.userCfg['highlight'].SetOption(themeName, element, value)
  1027.         
  1028.  
  1029.     
  1030.     def SetUserValue(self, configType, section, item, value):
  1031.         if idleConf.defaultCfg[configType].has_option(section, item):
  1032.             if idleConf.defaultCfg[configType].Get(section, item) == value:
  1033.                 return idleConf.userCfg[configType].RemoveOption(section, item)
  1034.             
  1035.         
  1036.         return idleConf.userCfg[configType].SetOption(section, item, value)
  1037.  
  1038.     
  1039.     def SaveAllChangedConfigs(self):
  1040.         '''Save configuration changes to the user config file.'''
  1041.         idleConf.userCfg['main'].Save()
  1042.         for configType in self.changedItems.keys():
  1043.             cfgTypeHasChanges = False
  1044.             for section in self.changedItems[configType].keys():
  1045.                 if section == 'HelpFiles':
  1046.                     idleConf.userCfg['main'].remove_section('HelpFiles')
  1047.                     cfgTypeHasChanges = True
  1048.                 
  1049.                 for item in self.changedItems[configType][section].keys():
  1050.                     value = self.changedItems[configType][section][item]
  1051.                     if self.SetUserValue(configType, section, item, value):
  1052.                         cfgTypeHasChanges = True
  1053.                         continue
  1054.                 
  1055.             
  1056.             if cfgTypeHasChanges:
  1057.                 idleConf.userCfg[configType].Save()
  1058.                 continue
  1059.         
  1060.         for configType in [
  1061.             'keys',
  1062.             'highlight']:
  1063.             idleConf.userCfg[configType].Save()
  1064.         
  1065.         self.ResetChangedItems()
  1066.  
  1067.     
  1068.     def ActivateConfigChanges(self):
  1069.         winInstances = self.parent.instance_dict.keys()
  1070.         for instance in winInstances:
  1071.             instance.ResetColorizer()
  1072.             instance.ResetFont()
  1073.             instance.ResetKeybindings()
  1074.             instance.reset_help_menu_entries()
  1075.         
  1076.  
  1077.     
  1078.     def Cancel(self):
  1079.         self.destroy()
  1080.  
  1081.     
  1082.     def Ok(self):
  1083.         self.Apply()
  1084.         self.destroy()
  1085.  
  1086.     
  1087.     def Apply(self):
  1088.         self.SaveAllChangedConfigs()
  1089.         self.ActivateConfigChanges()
  1090.  
  1091.     
  1092.     def Help(self):
  1093.         pass
  1094.  
  1095.  
  1096. if __name__ == '__main__':
  1097.     root = Tk()
  1098.     Button(root, text = 'Dialog', command = (lambda : ConfigDialog(root, 'Settings'))).pack()
  1099.     root.instance_dict = { }
  1100.     root.mainloop()
  1101.  
  1102.